package com.foreveross.proxyip.core.zk.task;

import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.dayatang.domain.InstanceFactory;
import com.foreveross.proxyip.core.pools.ChannelPool;
import com.foreveross.proxyip.core.pools.PoolsManager;
import com.foreveross.proxyip.core.redis.RedisLock;
import com.foreveross.proxyip.core.redis.RedisManager;
import com.foreveross.proxyip.core.zk.ZkAppCenter;
import com.foreveross.proxyip.entity.ChannelEntity;

public class NormalTask {
	
	private Logger logger = LoggerFactory.getLogger(NormalTask.class);

	public void reloadBaseCode() throws Exception{
		PoolsManager poolsManager =  InstanceFactory.getInstance(PoolsManager.class); 
		poolsManager.getPublicPool().initBaseCode();
		poolsManager.getDbPool().initBaseCode();
		for(ChannelPool channel:poolsManager.getChannelPoolMap().values()){
 			channel.initBaseCode();
		}
	}
	
	public synchronized void createNewAddChannelTask(String code) {
		PoolsManager poolsManager = InstanceFactory.getInstance(PoolsManager.class);
		ChannelPool channelPool = null;
		
		// 该渠道还未被创建,因为有可能一个渠道被多个集群应用多次触发 
		if (!poolsManager.getChannelPoolMap().containsKey(code)) {
			try {
				ZkAppCenter.getInstance().publishZkTaskByChannelCode(code);
				// 创建池
				channelPool = new ChannelPool(poolsManager.getPublicPool(), poolsManager.getChannelEntityByCode(code));
				poolsManager.getChannelPoolMap().put(code, channelPool);
				channelPool.open();
			} catch (Exception e) {
				logger.error("创建渠道任务时异常：", e);
			}
		}
	}
	
	public void createTask(String code) throws Exception{
		String leader = new String( ZkAppCenter.getInstance().getZK().getData(ZkAppCenter.getInstance().leaderPath, false, null));
		String checkInTaskPath = null;
		String checkOutTaskPath = null;
		Long startTime = System.currentTimeMillis();
		try{
		if(StringUtils.equals(leader, ZkAppCenter.getInstance().appName)){//如果是领导节点
			 checkInTaskPath = ZkAppCenter.getInstance().getTaskPath(ZkAppCenter.getInstance().getZK(), code+"_CheckInTask");
			 checkOutTaskPath = ZkAppCenter.getInstance().getTaskPath(ZkAppCenter.getInstance().getZK(), code+"_CheckOutTask");
			
			 String countStr = RedisManager.getInstance().get("create_task");
				Integer count = 0;
				if(StringUtils.isBlank(countStr)){
					countStr="0";
				}
			 count = Integer.parseInt(countStr)+1;
			 RedisManager.getInstance().setnx("create_task",count+"", 60);//领导必须先执行
		}else{
			RedisLock lock = new RedisLock("create_task_lock");
			try{
				while(System.currentTimeMillis()-startTime<60000){//一分钟超时
					String checkCountStr = RedisManager.getInstance().get("create_task");
					if(StringUtils.isBlank(checkCountStr)){ //领导还没执行
						continue;
					}else{
						Integer count = Integer.parseInt(checkCountStr)+1;
						RedisManager.getInstance().setnx("create_task",count+"", 60);
						break;
					}
				}
			}finally{
				lock.unlock();
			}
		}
		ZkAppCenter.getInstance().getZK().getData(checkInTaskPath, true, null);
		ZkAppCenter.getInstance().getZK().getData(checkOutTaskPath, true, null);
		}finally{
			String countStr = RedisManager.getInstance().get("create_task");
			Integer count = Integer.parseInt(countStr);
			Integer appCount = ZkAppCenter.getInstance().getAppsSize();
			if(count>=appCount){
				 RedisManager.getInstance().del("create_task");
			}
		}
	}
	
	public void stopChannel(String code) throws Exception{
		PoolsManager poolsManager =  InstanceFactory.getInstance(PoolsManager.class); 
		ChannelPool pool = poolsManager.getChannelPoolMap().get(code);
		pool.destroy();
		poolsManager.getChannelPoolMap().remove(code);
		ZkAppCenter.getInstance().taskSet.remove(code+"_CheckInTask");
		ZkAppCenter.getInstance().taskSet.remove(code+"_CheckOutTask");
	}
	
}
